#ifndef __stm32_OS__LIST__H__
#define __stm32_OS__LIST__H__

#include "basic_types.h"

struct stm32_list_head {
    struct stm32_list_head *next, *prev;
};

typedef struct stm32_list_head stm32_LIST_S, stm32_list_t;

#define STM32_LIST_HEAD_INIT(name) { &(name), &(name) }

#define STM32_LIST_HEAD(name) \
    struct stm32_list_head name = STM32_LIST_HEAD_INIT(name)

#define STM32_INIT_LIST_HEAD(ptr) do { \
    (ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)

static inline void __stm32_list_add(struct stm32_list_head * newnew,
        struct stm32_list_head * prev,
        struct stm32_list_head * next)
{
    next->prev = newnew;
    newnew->next = next;
    newnew->prev = prev;
    prev->next = newnew;
}

static inline void _stm32_list_add(struct stm32_list_head *newnew, struct stm32_list_head *head)
{
    __stm32_list_add(newnew, head, head->next);
}

static inline void _stm32_list_add_tail(struct stm32_list_head *newnew, struct stm32_list_head *head)
{
    __stm32_list_add(newnew, head->prev, head);
}

static inline void __stm32_list_del(struct stm32_list_head * prev,
        struct stm32_list_head * next)
{
    next->prev = prev;
    prev->next = next;
}

static inline void _stm32_list_del(struct stm32_list_head *entry)
{
    __stm32_list_del(entry->prev, entry->next);
}

static inline void _stm32_list_del_init(struct stm32_list_head *entry)
{
    __stm32_list_del(entry->prev, entry->next);
    STM32_INIT_LIST_HEAD(entry);
}

static inline int _stm32_list_empty(struct stm32_list_head *head)
{
    return head->next == head;
}

#define _stm32_list_entry(ptr, type, member) \
    ((type *)((uint8 *)(ptr)-(uint32)(&((type *)0)->member)))

#define _stm32_list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

#define _stm32_list_for_each_prev(pos, head) \
        for (pos = (head)->prev; pos != (head); pos = pos->prev)
    
#define _stm32_list_for_each_safe(pos, n, head) \
    for (pos = (head)->next, n = pos->next; pos != (head); \
            pos = n, n = pos->next)

#define _stm32_list_for_each_ex(pos, head, begin) \
    for (pos = (begin)->next; pos != (head); pos = (pos)->next)

#define _stm32_list_for_index(pos, i, head, index) \
    for (pos = (head)->next, i=0; (pos != (head) && i < index); pos = pos->next,i++)


static inline int _stm32_list_add_by_index(struct stm32_list_head *newnew, struct stm32_list_head *head, int index)
{
    struct stm32_list_head *pos = head;
    int i = -1;

    if (index >= 0) {
        for (pos = (head)->next, i=0; (pos != (head) && i < index); pos = pos->next,i++);
    }
    _stm32_list_add_tail (newnew, pos);
    return i;
}

VOID stm32_list_create(VOID * listhead);

VOID stm32_list_add(VOID *node,VOID * list);

VOID stm32_list_add_head(VOID *node,VOID * list);

VOID stm32_list_del(VOID *node);

VOID stm32_list_destory(VOID * listhead);

bool stm32_list_empty(VOID * listhead);

#define stm32_list_for_each(pos, head) \
 _stm32_list_for_each(pos, head)
 
#define stm32_list_for_each_safe(pos, n, head) \
 _stm32_list_for_each_safe(pos, n, head)
 
#define stm32_list_entry(ptr, type, member) \
 _stm32_list_entry(ptr, type, member)


#define stm32_list_isinqueue(item) ((item)->next != (item))

#define stm32_list_for_each_entry_safe(pos, n, head, member)			\
	for (pos = stm32_list_entry((head)->next, typeof(*pos), member),	\
		n = stm32_list_entry(pos->member.next, typeof(*pos), member);	\
	     &pos->member != (head); 					\
	     pos = n, n = stm32_list_entry(n->member.next, typeof(*n), member))

 
#endif /*__stm32_OS__LIST__H__*/


